#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import uuid
import logging
import time
from datetime import datetime
from typing import Dict, Any, Optional
from fastapi import APIRouter, UploadFile, File, Form, Depends, HTTPException, BackgroundTasks
from fastapi.responses import FileResponse
from pydantic import BaseModel

from document_processor.document_service import DocumentService
from api.models.document import DocumentResponse, ErrorResponse

# 创建路由
router = APIRouter(
    prefix="/api/document",
    tags=["document"],
    responses={
        404: {"model": ErrorResponse, "description": "Not found"},
        500: {"model": ErrorResponse, "description": "Server error"}
    }
)

# 获取日志记录器
logger = logging.getLogger(__name__)

# 存储任务信息
task_storage: Dict[str, Dict[str, Any]] = {}

def generate_unique_filename(original_filename: str) -> str:
    """生成唯一的文件名
    
    Args:
        original_filename: 原始文件名
        
    Returns:
        str: 唯一的文件名
    """
    # 获取文件扩展名
    _, ext = os.path.splitext(original_filename)
    # 生成时间戳
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    # 生成随机字符串
    random_str = str(uuid.uuid4())[:8]
    # 组合新的文件名
    return f"{timestamp}_{random_str}{ext}"

# 保存Markdown内容请求模型
class SaveMarkdownRequest(BaseModel):
    content: str

# 获取文档服务的依赖项
def get_document_service():
    """获取文档服务实例"""
    from main import config
    return DocumentService(config)

@router.post("/upload", response_model=DocumentResponse)
async def upload_document(
    background_tasks: BackgroundTasks,
    file: UploadFile = File(...),
    parser_option: str = Form("default"),
    image_option: str = Form("obs"),
    engine_name: Optional[str] = Form(None),
    document_service: DocumentService = Depends(get_document_service)
):
    """上传并处理文档
    
    将PDF或Word文档转换为Markdown格式。
    
    - **file**: 要上传的文件 (PDF或DOC/DOCX)
    - **parser_option**: 解析选项 (default/advanced)
    - **image_option**: 图片处理选项 (obs/local/remove)
    - **engine_name**: 要使用的引擎名称（可选）
    
    Returns:
        DocumentResponse: 包含处理后的Markdown内容
    """
    start_time = time.time()
    try:
        # 生成任务ID
        task_id = str(uuid.uuid4())
        
        # 生成唯一文件名
        unique_filename = generate_unique_filename(file.filename)
        
        logger.info(f"开始处理文档: {file.filename}, 任务ID: {task_id}, 唯一文件名: {unique_filename}")
        logger.info(f"解析选项: {parser_option}, 图片处理: {image_option}, 引擎: {engine_name or '默认'}")
        
        # 处理文档
        process_start = time.time()
        
        # 设置处理超时时间，默认2分钟
        timeout = 120  # 秒
        
        try:
            # 处理文档
            result = await document_service.process_document(
                file=file,
                parser_option=parser_option,
                image_option=image_option,
                engine_name=engine_name,
                unique_filename=unique_filename
            )
            process_time = time.time() - process_start
            logger.info(f"文档处理完成，耗时: {process_time:.2f}秒")
            
            # 保存任务信息
            task_storage[task_id] = {
                "file_name": unique_filename,
                "markdown_file": result["markdown_file"],
                "markdown_content": result["markdown"],
                "status": "completed",
                "process_time": process_time,
                "parser_option": parser_option,
                "engine_name": engine_name
            }
            
            # 安排清理临时文件的后台任务
            if "temp_dir" in result and result["temp_dir"]:
                background_tasks.add_task(
                    document_service.cleanup_temp_files,
                    result["temp_dir"]
                )
            
            total_time = time.time() - start_time
            logger.info(f"任务 {task_id} 总耗时: {total_time:.2f}秒")
            
            return {
                "file_name": unique_filename,
                "markdown": result["markdown"],
                "task_id": task_id,
                "process_time": process_time,
                "total_time": total_time,
                "engine_name": engine_name or "默认",
                "markdown_file": result["markdown_file"]
            }
            
        except Exception as e:
            error_time = time.time() - process_start
            logger.error(f"文档处理失败: {str(e)}, 耗时: {error_time:.2f}秒")
            raise HTTPException(status_code=500, detail=f"处理文档失败: {str(e)}")
    
    except Exception as e:
        total_time = time.time() - start_time
        logger.error(f"处理文档失败: {str(e)}, 耗时: {total_time:.2f}秒")
        raise HTTPException(status_code=500, detail=str(e))

@router.post("/save/{task_id}")
async def save_markdown(task_id: str, request: SaveMarkdownRequest):
    """保存修改后的Markdown内容
    
    Args:
        task_id: 任务ID
        request: 包含Markdown内容的请求体
        
    Returns:
        Dict: 保存结果
    """
    start_time = time.time()
    if task_id not in task_storage:
        raise HTTPException(status_code=404, detail="找不到指定的任务")
    
    try:
        # 获取任务信息
        task_info = task_storage[task_id]
        markdown_file = task_info["markdown_file"]
        
        # 更新内存中的内容
        task_info["markdown_content"] = request.content
        
        # 保存到文件
        with open(markdown_file, "w", encoding="utf-8") as f:
            f.write(request.content)
        
        save_time = time.time() - start_time
        logger.info(f"已保存Markdown内容: 任务ID {task_id}, 文件 {markdown_file}, 耗时: {save_time:.2f}秒")
        
        return {"success": True, "message": "Markdown内容已保存", "save_time": save_time}
    
    except Exception as e:
        save_time = time.time() - start_time
        logger.error(f"保存Markdown内容失败: {str(e)}, 耗时: {save_time:.2f}秒")
        raise HTTPException(status_code=500, detail=str(e))

@router.get("/download/{task_id}")
async def download_markdown(task_id: str):
    """下载处理后的Markdown文件
    
    Args:
        task_id: 任务ID
        
    Returns:
        FileResponse: Markdown文件响应
    """
    start_time = time.time()
    if task_id not in task_storage or "markdown_file" not in task_storage[task_id]:
        raise HTTPException(status_code=404, detail="找不到指定的任务或文件")
    
    markdown_file = task_storage[task_id]["markdown_file"]
    
    if not os.path.exists(markdown_file):
        raise HTTPException(status_code=404, detail="找不到指定的文件")
    
    download_time = time.time() - start_time
    logger.info(f"下载Markdown文件: 任务ID {task_id}, 文件 {markdown_file}, 耗时: {download_time:.2f}秒")
    
    return FileResponse(
        markdown_file,
        filename=os.path.basename(markdown_file),
        media_type="text/markdown"
    )

@router.get("/status/{task_id}")
async def get_task_status(task_id: str):
    """获取任务状态
    
    Args:
        task_id: 任务ID
        
    Returns:
        Dict: 任务状态信息
    """
    if task_id not in task_storage:
        raise HTTPException(status_code=404, detail="找不到指定的任务")
    
    task_info = task_storage[task_id]
    return {
        "task_id": task_id,
        "status": task_info["status"],
        "file_name": task_info["file_name"],
        "process_time": task_info.get("process_time", 0),
        "parser_option": task_info.get("parser_option", "default"),
        "engine_name": task_info.get("engine_name", "默认")
    }

class CreateMarkdownRequest(BaseModel):
    content: str
    filename: str = "editor_content.md"

@router.post("/create")
async def create_from_markdown(
    request: CreateMarkdownRequest,
    document_service: DocumentService = Depends(get_document_service)
):
    """从Markdown内容直接创建任务
    
    Args:
        request: 包含Markdown内容的请求体
        
    Returns:
        Dict: 创建结果，包含任务ID
    """
    start_time = time.time()
    
    try:
        # 生成任务ID
        task_id = str(uuid.uuid4())
        
        # 生成唯一文件名
        unique_filename = generate_unique_filename(request.filename)
        
        logger.info(f"从编辑器内容创建任务: {unique_filename}, 任务ID: {task_id}")
        
        # 保存Markdown内容到文件
        output_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "output")
        os.makedirs(output_dir, exist_ok=True)
        
        md_filename = os.path.splitext(unique_filename)[0] + ".md"
        md_file_path = os.path.join(output_dir, md_filename)
        
        with open(md_file_path, "w", encoding="utf-8") as f:
            f.write(request.content)
        
        # 保存任务信息
        task_storage[task_id] = {
            "file_name": unique_filename,
            "markdown_file": md_file_path,
            "markdown_content": request.content,
            "status": "completed",
            "process_time": 0,
            "parser_option": "editor",
            "engine_name": "editor"
        }
        
        create_time = time.time() - start_time
        logger.info(f"从编辑器内容创建任务成功，耗时: {create_time:.2f}秒")
        
        return {
            "file_name": unique_filename,
            "markdown": request.content,
            "task_id": task_id,
            "process_time": 0,
            "total_time": create_time,
            "engine_name": "editor",
            "markdown_file": md_file_path
        }
        
    except Exception as e:
        total_time = time.time() - start_time
        logger.error(f"从编辑器内容创建任务失败: {str(e)}, 耗时: {total_time:.2f}秒")
        raise HTTPException(status_code=500, detail=str(e)) 